﻿using System;

namespace zijian666.DI;


public abstract class ServiceProviderBase : IServiceProvider
{
    private readonly IServiceProvider _serviceProvider;

    internal ServiceProviderBase(IServiceProvider serviceProvider)
    {
        if (serviceProvider is null)
        {
            throw new ArgumentNullException(nameof(serviceProvider));
        }

        _serviceProvider = (serviceProvider as ServiceProviderBase)?._serviceProvider ?? serviceProvider;
    }

    /// <inheritdoc />
    public object? GetService(Type serviceType) => _serviceProvider.GetService(serviceType);

    // override object.Equals
    public override bool Equals(object obj)
    {
        return obj switch
        {
            null => false,
            ServiceProviderBase other => _serviceProvider == other._serviceProvider,
            IServiceProvider other => _serviceProvider == other,
            _ => false,
        };
    }

    // override object.GetHashCode
    public override int GetHashCode()
    {
        return _serviceProvider.GetHashCode();
    }

    public static bool operator ==(ServiceProviderBase left, IServiceProvider right)
    {
        return left?.Equals(right) ?? false;
    }
    public static bool operator !=(ServiceProviderBase left, IServiceProvider right)
    {
        return !(left?.Equals(right) ?? false);
    }
}

/// <summary>
/// 单例环境中的服务提供程序
/// </summary>
public class SingletonServiceProvider : ServiceProviderBase
{
    internal SingletonServiceProvider(IServiceProvider serviceProvider)
        : base(serviceProvider)
    {
    }
}

/// <summary>
/// 作用域环境中的服务提供程序
/// </summary>
public class ScopedServiceProvider : ServiceProviderBase
{
    internal ScopedServiceProvider(IServiceProvider serviceProvider) : base(serviceProvider)
    {
    }
}

/// <summary>
/// 瞬态环境中的服务提供程序
/// </summary>
public class TransientServiceProvider : ServiceProviderBase
{
    internal TransientServiceProvider(IServiceProvider serviceProvider) : base(serviceProvider)
    {
    }
}
